Skip to content

SpringBoot——自定义配置

读取配置文件的自定义属性(多个)

比如说我们想给Spring Security配置一个白名单,访问这些路径无需授权,我们可以先在application.yml中添添加如下配置

secure:
  ignored:
    urls:
      - /
      - /swagger-ui/
      - /*.html
      - /favicon.ico
      - /**/*.html
      - /**/*.css
      - /**/*.js
      - /swagger-resources/**
      - /v2/api-docs/**

之后创建一个属性类,使用@ConfigurationProperties注解配置好这些属性的前缀,再定义一个urls属性与属性文件相对应即可。

/**
 * @auther macrozheng
 * @description 用于配置白名单资源路径
 * @date 2018/11/5
 * @github https://github.com/macrozheng
 */
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "secure.ignored")
public class IgnoreUrlsConfig {

    private List<String> urls = new ArrayList<>();

}

自定义Bean覆盖自动配置

这里先说明两个概念,一个是自定义配置的使用;另外一个就是这一个章节打算讲述的自定义 Bean;

自定义配置: 通过外部化配置(如 application.yml@ConfigurationProperties)或编程式配置(如 @Configuration 类)来修改应用行为,不涉及覆盖 Bean

常见的一些场景:配置文件中修改端口号、数据库连接信息等;

TODO 后面继续看(deepseek继续)

虽然自动配置很好用,但有时候自动配置的Bean并不能满足你的需要,我们可以自己定义相同的Bean来覆盖自动配置中的Bean。

例如当我们使用Spring Security来保护应用安全时,由于自动配置并不能满足我们的需求,我们需要自定义基于SecurityFilterChain对象的配置。这里我们自定义了很多配置,比如将基于Session的认证改为使用JWT令牌、配置了一些路径的无授权访问,自定义了登录接口路径,禁用了csrf功能等。

/**
 * @auther macrozheng
 * @description SpringSecurity的配置
 * @date 2018/4/26
 * @github https://github.com/macrozheng
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig{
    @Autowired
    private UmsAdminService adminService;
    @Autowired
    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;
    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
    @Autowired
    private IgnoreUrlsConfig ignoreUrlsConfig;

    @Bean
    SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        List<String> urls = ignoreUrlsConfig.getUrls();
        String[] urlArray = ArrayUtil.toArray(urls, String.class);
        httpSecurity.csrf()// 由于使用的是JWT,我们这里不需要csrf
                .disable()
                .sessionManagement()// 基于token,所以不需要session
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.GET,urlArray) // 允许对于网站静态资源的无授权访问
                .permitAll()
                .antMatchers(HttpMethod.POST,urlArray) // 允许对于网站静态资源的无授权访问
                .permitAll()
                .antMatchers("/admin/login")// 对登录注册要允许匿名访问
                .permitAll()
                .antMatchers(HttpMethod.OPTIONS)//跨域请求会先进行一次options请求
                .permitAll()
                .anyRequest()// 除上面外的所有请求全部需要鉴权认证
                .authenticated();
        // 禁用缓存
        httpSecurity.headers().cacheControl();
        // 添加JWT filter
        httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        //添加自定义未授权和未登录结果返回
        httpSecurity.exceptionHandling()
                .accessDeniedHandler(restfulAccessDeniedHandler)
                .authenticationEntryPoint(restAuthenticationEntryPoint);
        return httpSecurity.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        //获取登录用户信息
        return username -> {
            AdminUserDetails admin = adminService.getAdminByUsername(username);
            if (admin != null) {
                return admin;
            }
            throw new UsernameNotFoundException("用户名或密码错误");
        };
    }

    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        return new JwtAuthenticationTokenFilter();
    }

}

讲解说明:

核心概念:自定义Bean覆盖自动配置

  • 自动配置的局限性:Spring Boot的自动配置虽然方便,但可能无法满足特定需求。
  • 覆盖机制:通过显式定义相同类型的Bean(使用@Bean注解)可以覆盖自动配置提供的默认Bean。